[release-1.7.3]: https://github.com/HuolalaTech/page-spy-web/releases/tag/v1.7.3
[public-data-event]: https://github.com/HuolalaTech/page-spy/blob/main/docs/plugin_zh.md#行为约定

import modalImg from '@/assets/image/screenshot/modal.png';
import replayImg from '@/assets/image/screenshot/replay-page.png';
import replayGif from '@/assets/image/screenshot/replay-page.gif';
import mpDataHarborImg from '@/assets/image/screenshot/mp-data-harbor.png';

**日志回放**，顾名思义是重新播放之前产生的日志。那么为什么要播放之前的日志？之前的日志从哪来？如何重新播放？我们一一来看。

<a href={replayGif} target="_blank">
  <img src={replayGif} />
</a>

## 为什么#why

以往，PageSpy 在线调试解决了很多棘手的问题，但使用 PageSpy 有一个前提条件：「客户端和调试端必须同时在线」。这个前置条件不仅局限了 PageSpy 的使用场景，比如：

- 针对一个问题要同时投入开发和测试两个人力；
- 调试期间客户端退到后台导致连接断开了；

同时也给 PageSpy 自身带来边边框框，比如：

- 要考虑收集的数据体积、网络传输的压力；

为了解决这些问题、使用时获得更大自由度，PageSpy 在 [1.7.3][release-1.7.3] 版本中提供了日志回放的功能！

## 日志从哪来#where

在 PageSpy 的 SDK 支持 [注册插件](./plugins) 后，开发团队第一时间推进 [DataHarborPlugin]({VITE_PLUGIN_DATA_HARBOR}) 插件的研发。

> `Data Harbor`，数据港口。
> 
> 心智模型：PageSpy 产生的数据会源源不断的被送到 “数据港口”，在对数据进行整理、打包、压缩后，“数据港口” 将数据存放在 “集装箱”（内存或本地临时文件）中，等待下一步指示。

它在内部监听 `"public-data"` 事件（[什么是 "public-data" 事件？](./plugins#convention)），进而实现离线缓存数据的功能，同时在 SDK 渲染的控件中提供上传、下载数据的功能。当客户端发现问题时，测试同学可以直接上传或者下载数据，这一创新打破了以往「客户端和调试端必须同时在线」的前提要求。

## 如何使用#how-to-use

### 在浏览器中使用#browser

> 如果仅需要 PageSpy 的离线日志回放功能，我们推荐 [O-Spy](#use-ospy) 的使用方式，集成更简单。

#### 第一步：客户端引入 SDK 和插件#step-1

```html
<html>
  <head>
    <!-- 1. 加载 PageSpy -->
    <script src="{deployUrl}/page-spy/index.min.js"></script>
    <!-- 2. 加载 DataHarbor 插件：缓存离线日志数据，提供下载 / 上传日志功能 -->
    <script src="{deployUrl}/plugin/data-harbor/index.min.js"></script>
    <!-- 3. 同时可以加载 RRWeb 插件，将用户操作轨迹记录到离线日志中 -->
    <script src="{deployUrl}/plugin/rrweb/index.min.js"></script>

    <script>
      // 4. 注册插件，config 信息查看：https://github.com/HuolalaTech/page-spy/blob/main/packages/page-spy-plugin-data-harbor
      PageSpy.registerPlugin(new DataHarborPlugin(config));
      PageSpy.registerPlugin(new RRWebPlugin());

      // 5. 实例化 PageSpy
      window.$pageSpy = new PageSpy({
        // 如果不想 SDK 和调试端建立实时连接，可以开启离线模式
        // offline: true
      });
    </script>
  </head>
</html>
```

引入成功后页面右下方会出现 PageSpy 的悬浮球，点击悬浮球出现的弹窗中应该包含了上传和下载的按钮。

<a href={modalImg} target="_blank">
  <img src={modalImg} />
</a>

#### 第二步：回放日志#step-2

进入调试端，点击顶部菜单「开始调试 - 日志回放」进入回放列表页面，选择上一步上传 / 下载的 json 数据即可开始使用回放功能！

<a href={replayImg} target="_blank">
  <img src={replayImg} />
</a>

#### 配合其他插件使用#plugins

DataHarborPlugin 本身只收集数据、提供数据处理的功能，PageSpy 另外还提供了：

- [RRWebPlugin]({VITE_PLUGIN_RRWEB}): 使用 `rrweb` 记录 DOM 更新，在调试端的「日志回放」面板左侧用户可以看到页面的操作轨迹；

### 使用 O-Spy#use-ospy

[O-Spy](/o-spy) 的 SDK 即插即用、无需部署。它打包了 PageSpy / DataHarborPlugin / RRWebPlugin，内置 PageSpy 在离线状态下的最佳实践配置、同时支持自定义主题，使用非常简单。

与框架无关，你可以任选一种方式在项目中引入。

import { ImportGuide } from '@/pages/OSpy/components/ImportGuide';

<ImportGuide />

引入成功后就会看到右下角出现的 "问题反馈" 可拖拽的组件。

#### 自定义主题示例#customize-example

import { CustomizeExample } from '@/pages/OSpy/components/Customize';

<CustomizeExample />

### 在小程序中使用#mp

小程序环境也支持离线日志回放，步骤如下：

#### 第一步：安装小程序专用插件#mp-step-1
```bash
yarn add @huolala-tech/page-spy-plugin-mp-data-harbor
```

#### 第二步：注册该插件#mp-step-2
```ts
import PageSpy from '@huolala-tech/page-spy-wechat';
import DataHarborPlugin from '@huolala-tech/page-spy-plugin-mp-data-harbor';

// 注册插件，config 信息查看：https://github.com/HuolalaTech/page-spy/blob/main/packages/page-spy-plugin-mp-data-harbor
const $dataHarborPlugin = new DataHarborPlugin(config)
PageSpy.registerPlugin($dataHarborPlugin);

const $pageSpy = new PageSpy({
  // ...
})

```

#### 第三步：上传离线日志#mp-step-3

有两种方式可以上传离线日志：

1. 调用插件实例上的 `upload()` 方法：
```ts
$dataHarborPlugin.upload().then(() => {
  console.log('上传成功');
})
```

2. 注册小程序 DataHarbor 插件后，PageSpy 的调试菜单中会出现一个 「上传离线日志」按钮，点击即可上传离线日志：

<a href={mpDataHarborImg} target="_blank">
  <img style={{width: 375}} src={mpDataHarborImg} />
</a>

### 差异#diff

1. 小程序环境不支持界面录制，也没有配套的 `RRWebPlugin`。

2. 小程序环境离线日志仅支持上传，不支持下载。

## FAQ#faq

1. 如何手动操作上传 / 下载日志？

[点击查看](./data-harbor#onOfflineLog)。

2. 离线日志存储在哪里？

`DataHarborPlugin` 收到数据后，会先放入内存的数组中，当数组里存储的数据体积达到临界值时会将数据写入临时文件，这个临界值默认情况下是 10M。你也可以自行配置:

```ts
new DataHarborPlugin({
  maximum: 1 * 1024 * 1024, // 内存中的数据记录达到 1M 时写入临时文件
})
```